﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace A2DFramework.HttpLoadBalancer.Connection
{
    public static class ConnectionWorkerPool
    {
        private static List<ConnectionWrapper> connections = new List<ConnectionWrapper>();
        private static object lock_connections = new object();
        private static int maxConnections = 100;

        public static ConnectionWorker GetOne(Socket socket)
        { 
            lock(lock_connections)
            {
            waiting4Resource:
                ConnectionWrapper wrapper=null;
                ConnectionWorker conn=null;

                if (connections.Count < maxConnections)
                {
                    wrapper = new ConnectionWrapper();

                    conn = new ConnectionWorker(socket);

                    wrapper.Connection=conn;
                    wrapper.ReturnedToPool=true;

                    connections.Add(wrapper);
                }
                else
                {
                    foreach(var wp in connections)
                    {
                        if(wp.ReturnedToPool)
                        {
                            wrapper=wp;
                            conn=wp.Connection;
                            conn.SetSocket(socket);
                            break;
                        }
                    }
                }

                if (conn == null)
                {
                    Thread.Sleep(100);
                    goto waiting4Resource;
                }
                conn.Prepare();

                wrapper.ReturnedToPool=false;

                return conn;
            }
        }

        public static void ReturnToPool(ConnectionWorker conn)
        {
            conn.ShutDown();

            lock(lock_connections)
            {
                foreach (var wp in connections)
                {
                    if (wp.Connection.Equals(conn))
                    {
                        wp.ReturnedToPool = true;
                        break;
                    }
                }
            }
        }
    }


    class ConnectionWrapper
    {
        public ConnectionWorker Connection { get; set; }

        public bool ReturnedToPool { get; set; }
    }
}
